package com.azt.provider.impl;

import com.azt.api.dto.HandleCoinDto;
import com.azt.api.pojo.CoinRecord;
import com.azt.api.pojo.CoinRule;
import com.azt.api.pojo.CompanyAccount;
import com.azt.api.service.CoinService;
import com.azt.model.page.Pagination;
import com.azt.provider.mapper.CoinRecordMapper;
import com.azt.provider.mapper.CoinRuleMapper;
import com.azt.provider.mapper.CompanyAccountMapper;
import com.azt.utils.MathUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xiaoleilu.hutool.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class CoinServiceImpl implements CoinService {
	
	@Autowired
	private CompanyAccountMapper companyAccountMapper;
	
	@Autowired
	private CoinRecordMapper coinRecordMapper;
	
	@Autowired
	private CoinRuleMapper coinRuleMapper;

	@Override
	public List<CoinRecord> findCoinRecord(int companyId) {
		CoinRecord record = new CoinRecord();
		record.setCompanyId(companyId);
		PageHelper.orderBy("id desc");
		return coinRecordMapper.select(record);
	}

	@Override
	public Pagination coinManagerList(int pageno, int pagesize, Map<String, String> params) {
		Page<Object> startPage = PageHelper.startPage(pageno, pagesize);
		List<CompanyAccount> coinManagerList=companyAccountMapper.coinManagerList(params);
		Pagination p = new Pagination(startPage, coinManagerList);
		p.setList(coinManagerList);
		p.setParams(params);
		return p;
	}

	@Override
	public Pagination coinRecordList(int pageno, int pagesize, Map<String, String> params) {
		Page<Object> startPage = PageHelper.startPage(pageno, pagesize);
		List<CoinRecord> coinRecordList=coinRecordMapper.selectMainCoinRecord(params);
		Pagination p = new Pagination(startPage, coinRecordList);
		p.setList(coinRecordList);
		p.setParams(params);
		return p;
	}

	@Override
	public Map<String, String> useAnNouseCoin(String companyId) {
		Map<String, String> params=new HashMap<>();
		if(companyId!=null){
			params.put("so_companyId", companyId);
		}
		return coinRecordMapper.useAnNouseCoin(params).get(0);
	}

	@Override
	public Pagination coinRuleList(int pageno, int pagesize, Map<String, String> params) {
		Page<Object> startPage = PageHelper.startPage(pageno, pagesize);
		List<CoinRule> coinRuleList=coinRuleMapper.selectCoineList(params);
		Pagination p = new Pagination(startPage, coinRuleList);
		p.setList(coinRuleList);
		p.setParams(params);
		return p;
	}

	@Override
	public void saveCoinRule(CoinRule coinRule) {
		if(coinRule != null) {
			if(coinRule.getId() != null) {
				coinRuleMapper.updateByPrimaryKey(coinRule);
			} else {
				coinRuleMapper.insertSelective(coinRule);
			}
		}
	}

	@Override
	public void removeCoinRule(Integer id) {
		CoinRule rule=coinRuleMapper.selectByPrimaryKey(id);
		if(rule.getRemoved().equals(0)){
			rule.setRemoved(1);
		}else{
			rule.setRemoved(0);
		}
		coinRuleMapper.updateByPrimaryKeySelective(rule);
	}

    @Override
    public void handleCoin(HandleCoinDto hcd){
		CoinRule rule = this.getEffectiveRule(hcd.getRuleCode());
		if (rule != null) {
			CoinRecord cr = new CoinRecord(rule);
			cr.setCompanyId(hcd.getCompanyId());
			cr.setBatchId(hcd.getPayNumber());
			cr.setCoinAmount(hcd.getCoinAmount().doubleValue());
			cr.setUserId(hcd.getUserId());
			cr.setOperateid(hcd.getOperateId());
			cr.setOrderNum(hcd.getOrderNumber());
			cr.setPayAmount(hcd.getPayAmount());
			coinRecordMapper.insert(cr);
		}
	}

	@Override
	public void addCompanyCoin(String ruleCode, int companyId, Double money, String descr, Integer operateId) {
		CoinRule rule = getEffectiveRule(ruleCode);
		if(rule != null) {
			double coinAmount = 0;
			if(rule.getType().intValue() == CoinRule.TYPE_NUM && rule.getAmount() != null) {
				//数量
				coinAmount = rule.getAmount();
			} else if(rule.getType().intValue() == CoinRule.TYPE_PRO && rule.getCoinAmount() != null && rule.getOrderAmount() != null && money != null) {
				//比例
				coinAmount = MathUtil.multiply(MathUtil.divide(rule.getCoinAmount().doubleValue(), rule.getOrderAmount().doubleValue()), money, 2);
			} else if(rule.getType().intValue() == CoinRule.TYPE_BOTH && rule.getAmount() != null && rule.getCoinAmount() != null && rule.getOrderAmount() != null) {
				//混合
				coinAmount = MathUtil.add(rule.getAmount(), money != null ? MathUtil.multiply(MathUtil.divide(rule.getCoinAmount().doubleValue(), rule.getOrderAmount().doubleValue(), 2), money) : 0);
			}
			if(coinAmount != 0) {
				CoinRecord record = new CoinRecord();
				record.setCompanyId(companyId);
				record.setRuleCode(ruleCode);
				record.setDescr(StrUtil.isBlank(descr) ? rule.getTitle() : descr);
				record.setCoinAmount(coinAmount);
				record.setOperateType(rule.getOperateType());
				record.setOperateid(operateId);
				coinRecordMapper.insertSelective(record);
			}
		}
	}

	@Override
	public int getCoinByCompanyId(int companyId) {
//		List<CompanyAccount> companyAccounts = companyAccountMapper.selectByCompanyId(companyId);
//		if (companyAccounts.size() > 0) {
//			return companyAccounts.get(0).getUscoins() == null ? 0 : companyAccounts.get(0).getUscoins();
//		}
		CompanyAccount companyAccount = companyAccountMapper.getCompanyAccount(companyId);//表中记录的拥有的安装币

		int uscoins = 0;
		if (companyAccount != null) {
			uscoins = companyAccount.getUscoins() == null ? 0 : companyAccount.getUscoins();//待复核的订单中已使用的安装币
		}

		int uc = coinRuleMapper.getUsedCoinByCompanyId(companyId);

		return uscoins - uc;
	}

	@Override
	public CoinRule getEffectiveRule(String ruleCode) {
		return coinRuleMapper.selectEffectiveRule(ruleCode);
	}

	@Override
	public int getCanHandleCoin(Double tranAmount, String ruleCode, int companyId){
		CoinRule rule = this.getEffectiveRule(ruleCode);
		if (rule != null) {
			if (rule.getOperateType().compareTo(CoinRule.SUB_OPERATE_TYPE) == 0) {//减安装币
				Integer coinByCompanyId = getCoinByCompanyId(companyId);
				if (rule.getType().compareTo(CoinRule.TYPE_NUM) == 0) {//按数量
					return coinByCompanyId.compareTo(rule.getAmount().intValue()) > 0 ? rule.getAmount().intValue() : coinByCompanyId;
				}
				if (tranAmount != null && rule.getType().compareTo(CoinRule.TYPE_PRO) == 0) {//按比例
					int coins = (int) Math.floor(tranAmount * (rule.getCoinAmount() / rule.getOrderAmount()));
					return coinByCompanyId.compareTo(coins) > 0 ? coins : coinByCompanyId;
				}
				if (tranAmount != null && rule.getType().compareTo(CoinRule.TYPE_BOTH) == 0) {//混合型
					int coins = (int) Math.floor(tranAmount * (rule.getCoinAmount() / rule.getOrderAmount())) + rule.getAmount().intValue();
					return coinByCompanyId.compareTo(coins) > 0 ? coins : coinByCompanyId;
				}
			} else {//加安装币
				if (rule.getType().compareTo(CoinRule.TYPE_NUM) == 0) {//按数量
					return rule.getAmount().intValue();
				}
				if (tranAmount != null && rule.getType().compareTo(CoinRule.TYPE_PRO) == 0) {//按比例
					int coins = (int) Math.floor(tranAmount * (rule.getCoinAmount() / rule.getOrderAmount()));
					return coins;
				}
				if (tranAmount != null && rule.getType().compareTo(CoinRule.TYPE_BOTH) == 0) {//混合型
					int coins = (int) Math.floor(tranAmount * (rule.getCoinAmount() / rule.getOrderAmount()));
					int nums = rule.getAmount().intValue();
					return coins + nums;
				}
			}
		}
		return 0;
	}

	@Override
	public CoinRule selectRuleBycode(String code) {
		CoinRule rule=new CoinRule();
		rule.setRuleCode(code);
		rule.setRemoved(0);
		return coinRuleMapper.selectOne(rule);
	}

	@Override
	public void adminChangeCoin(CoinRecord coinrecord) {
		/*CompanyAccount companyAccount=companyAccountMapper.getCompanyAccount(coinrecord.getCompanyId());
		Integer coins=Integer.parseInt(new java.text.DecimalFormat("0").format(coinrecord.getCoinAmount()));
		companyAccount.setUscoins(companyAccount.getUscoins()-coins);
		companyAccount.setDiscoins(companyAccount.getDiscoins()+coins);
		
		companyAccountMapper.updateByPrimaryKeySelective(companyAccount);*/
		coinRecordMapper.insertSelective(coinrecord);
	}

	@Override
	public List<CoinRule> findValidCoinRule() {
		CoinRule rule = new CoinRule();
		rule.setRemoved(0);
		Example example = new Example(CoinRule.class);
		example.createCriteria().andEqualTo(rule).andCondition("now() between starttime and endtime");
		return coinRuleMapper.selectByExample(example);
	}

	@Override
	public List<Map<String, Object>> getCoinRecord(Integer companyId) {
		return coinRecordMapper.getCoinRecord(companyId);
	}

}
